/*
 * Created by SharpDevelop.
 * User: Guy Fomi
 * Date: 2/6/2011
 * Time: 2:14 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using FileSystemDatabase;
using TomatoSynchronizer.Entities;
using Newtonsoft.Json.Linq;

namespace TomatoSynchronizer.Store
{
	/// <summary>
	/// Description of ProductStore.
	/// </summary>
	public class ProductStore : IStore<Product>
	{
		private Site _site;
		public Site site {
			get { return _site; }
			set { _site = value; }
		}
		
		private HtmlWeb _client;
		
		private JsonDatabase db;
		public void PersistItems(List<Product> Products)
		{
			db.Write<List<Product>>(Products,_site.Name);
		}

		public void PersistItem(Product product)
		{
			db.Write<Product>(product,product.products_id);
		}
		
		public ProductStore(Site site,HtmlWeb client)
		{
			db = new JsonDatabase("sites/" + site.Name + "/Products");
			_site = site;
			_client = client;
		}
		
		public Product GetItem(string ProductId)
		{
			CategoryStore categorieStore = new CategoryStore(_site,_client);
			
			List<Product> entries = new List<Product>();
//			JObject product = null;
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=load_product&module=products&products_id=" + ProductId);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "data")
				{
					Product product = (Product)json[key];
					
					//we load the product categories
					int i = 0;
					Category[] categories = new Category[product.categories_id.Length];
					foreach(string id in product.categories_id)
					{
						categories[i] = categorieStore.LoadItem(id);
						i++;
					}
					
					product.Categories = categories;
					entries.Add(product);
				}
			}
			
			return entries[0];
		}
		
		public List<Product> GetItems()
		{
			List<Product> records = new List<Product>();
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=list_products&categories_id=0&module=products");
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "records")
				{
					ArrayList recs = (ArrayList)json[key];
					for(int i = 0;i < recs.Count;i++)
					{
						Product record = (Product)recs[i];
						Product product = GetItem(record.products_id);
						product.Attributs = GetItemAttributes(record.products_id);
						product.Images = GetItemImages(record.products_id);
						product.Variants_products = GetItemVariants(product);
						product.Xsell_products = GetItemXsell(record.products_id);
						product.Products_attachments = GetItemAttachments(product.products_id);
						product.Accessories = GetItemAccessories(product.products_id);
						records.Add(product);
					}
				}
			}
			
			return records;
		}
		
		private List<XsellProduct> GetItemXsell(string productId)
		{
			List<XsellProduct> xsell_products = new List<XsellProduct>();
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=get_xsell_products&module=products&products_id=" + productId);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "records")
				{
					ArrayList recs = (ArrayList)json[key];
					for(int i = 0;i < recs.Count;i++)
					{
						XsellProduct xsell_product = (XsellProduct)recs[i];
						xsell_products.Add(xsell_product);
					}
				}
			}
			
			return xsell_products;
		}

		private List<ProductAccessory> GetItemAccessories(string productId)
		{
			List<ProductAccessory> accessories = new List<ProductAccessory>();
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=get_accessories&module=products&products_id=" + productId);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "records")
				{
					ArrayList recs = (ArrayList)json[key];
					for(int i = 0;i < recs.Count;i++)
					{
						ProductAccessory accessory = (ProductAccessory)recs[i];
						accessories.Add(accessory);
					}
				}
			}
			
			return accessories;
		}
		
		private List<ProductAttachment> GetItemAttachments(string productId)
		{
			List<ProductAttachment> products_attachments = new List<ProductAttachment>();
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=load_products_attachments&module=products&products_id=" + productId);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "records")
				{
					ArrayList recs = (ArrayList)json[key];
					for(int i = 0;i < recs.Count;i++)
					{
						ProductAttachment product_attachment = (ProductAttachment)recs[i];
						products_attachments.Add(product_attachment);
					}
				}
			}
			
			return products_attachments;
		}
		
		private List<ProductVariant> GetItemVariants(Product product)
		{
			List<ProductVariant> variants_product = new List<ProductVariant>();
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=get_variants_products&module=products&products_id=" + product.products_id);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "records")
				{
					ArrayList recs = (ArrayList)json[key];
					for(int i = 0;i < recs.Count;i++)
					{						
						ProductVariant variant_product = (ProductVariant)recs[i];	
						foreach(ProductImage image in product.Images)
						{
							if(image.id.ToString() == variant_product.data.variants_image)
							{
								variant_product.data.Image = image;
							}
						}
						variants_product.Add(variant_product);
					}
				}
			}
			
			return variants_product;
		}
		
		private List<ProductImage> GetItemImages(string productId)
		{
			List<ProductImage> images = new List<ProductImage>();
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=get_images&module=products&products_id=" + productId);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "records")
				{
					ArrayList recs = (ArrayList)json[key];
					for(int i = 0;i < recs.Count;i++)
					{
						ProductImage image = (ProductImage)recs[i];
						if(!string.IsNullOrEmpty(image.name))
						{
							Utility.DownloadImage(_site.Url + "/images/products/originals/" + image.name,"sites/" + _site.Name + "/Products/Images/originals/");
						}
						images.Add(image);
					}
				}
			}
			
			return images;
		}
		
		private List<ProductAttribut> GetItemAttributes(string productId)
		{
			List<ProductAttribut> attributs = new List<ProductAttribut>();
			
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=get_attributes&module=products&products_id=" + productId);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach(string key in json.Keys)
			{
				if(key == "attributes")
				{
					ArrayList recs = (ArrayList)json[key];
					for(int i = 0;i < recs.Count;i++)
					{
						ProductAttribut attribut = (ProductAttribut)recs[i];
						attributs.Add(attribut);
					}
				}
			}
			
			return attributs;
		}				
		
		public void Truncate()
		{
			throw new NotImplementedException();
		}				
		
		public bool MoveItem(string itemId, string folderId)
		{
			throw new NotImplementedException();
		}
		
		public bool DeleteItem(string itemId)
		{
			throw new NotImplementedException();
		}
		
		public Product[] LoadItems()
		{
			Product[] _products = db.Read<Product>();
			
			foreach(Product _product in _products)
			{
				_product.Store = this;
			}
			return _products;
		}
		
		public Product LoadItem(string itemId)
		{
			Product product = db.Read<Product>(itemId);
			if(product != null)
			{
				product.Store = this;
				return product;
			}
			
			return null;
		}
		
		public bool Contains(Product item)
		{
			throw new NotImplementedException();
		}				
		
		public bool UpdateItem(Product item)
		{
			throw new NotImplementedException();
		}
		
		public string InsertItem(Product item)
		{
			throw new NotImplementedException();
		}
	}
}
